#ifndef SCENE
#define SCENE

#include <map>
#include <vector>
#include <iostream>
//#include <GL/glext.h>
#include <SDL.h>
//#include <GL/glut.h>

#ifdef WIN32
#include <Windows.h>
#endif
#include <GL/glew.h>

#include <qstring.h>

class Objet;
class Shader;
class catmullCurve;
class Camera;
class ParticleSystem;
class sound;
//class Timer;
class Note;
class QTime;

using namespace std;
typedef int NOTEMASK;

class Scene
{
	public:
		Scene();
		Scene(Scene*);
		~Scene();

		void init(int playernum);
		void draw();
		void animate(float dt);
		void processJoy();
		void setAnimated(bool b){animating=b; m_playmode= (b) ? PLAY : PAUSE ;};
		void setCamera(Camera *cam){m_camera=cam;};
		bool isAnimated() {return animating;};
		void playpause();
		void clean();
		void layoutNotes();
		void changeTabSpeed(float newscale);
		void setSong(sound* song){m_song=song;};
		void setupEnv(int playernb);

		Objet* getObject(QString);
		Shader* getShader(QString);
		GLuint getTexture(QString);
		int getGeometry(QString);
		sound* getSound(QString);
		
		catmullCurve* getPath(QString);
		Camera* getCamera(QString);
		ParticleSystem* getParticleSystem(QString);
		QString getName(){return m_name;}
		int getScore() {return m_score;}
		int getMultiplier() {return m_multiplier;}
		int getStreak() {return m_streak;}
		std::multimap<double,Note*> getTablature() {return m_tablature;}
		void setTablature(multimap<double,Note*> newtab) {m_tablature=newtab;}


		void addObject(QString,Objet*);
		void addShader(QString,Shader*);
		void addTexture(QString,GLuint);
		void addGeometry(QString,int);
		void addSound(QString,sound*);
		void addPath(QString,catmullCurve*);
		void addCamera(QString,Camera*);
		void addParticleSystem(QString,ParticleSystem*);
		void setName(QString s);

		void setButtons(int green, int red, int yellow, int blue, int orange, int strumup, int strumdown, int start, int select, int rock);

		typedef multimap<double,Note*>::iterator tab_iterator;
		// TODO : remplacer la multimap par un vecteur, car on a pas besoin des fonctions de tri ...

		tab_iterator tab_it;
		typedef std::map<QString, Objet*>::iterator obj_iterator;
		typedef std::map<QString, catmullCurve*>::iterator path_iterator;
		typedef std::map<QString, sound*>::iterator sound_iterator;
		enum {PLAY,PAUSE,TRAINING,PLAYBACK} m_playmode;
		enum {JOYSTICK,KEYBOARD} m_controltype;

	private:
		bool validateStrum(NOTEMASK,bool strum);
		void findNextStrumTime(float*,float*,Note *n1=NULL,Note *n2=NULL);
		void incrementScore(int chord);
		void decrementScore(bool sound);
		NOTEMASK getFretStatus();
		void playback();
		void checkCrowd(bool);

		std::multimap<double,Note*> m_tablature;

		int m_score;
		int m_streak;
		int m_streakmax;
		float m_percent;
		int m_multiplier;
		int m_crowdmeter;

		bool animating;
		float lastSongTime;
		float songtime_corrected; //en secondes

		Note *lastStrummedNote;
		float lastStrumTime;
		NOTEMASK lastStrummedNoteMask;
		vector<Note*> lastStrummedChord;
		float ltime;
		float utime;
		Note *lnote;
		Note *unote;

		QString m_name;
		int m_playernb;
		map<QString, Objet*> m_objets;
		map<QString, Shader*> m_shaders;
		map<QString, catmullCurve*> m_paths;
		map<QString, GLuint> m_textures;
		map<QString, int> m_geometries;
		map<QString, sound*> m_sounds;
		map<QString, Camera*> m_cameras;
		map<QString, ParticleSystem*> m_psystems;

		vector<Objet*> pickups;
		vector<Objet*> m_transpObjs;
		Objet* neck;
		Objet* lifebar;
		sound* m_song;
		Camera* m_camera;
		ParticleSystem* parts1;

		int BGREEN, BRED, BYELLOW, BBLUE, BORANGE, BSTRUMUP, BSTRUMPDOWN, BSTART, BSELECT, BROCK;

		//Timer* timer1;
		
	  QTime* timer1;

		static bool m_pileRead;
		static SDL_Event* eventpile;
};

#endif
